/*
 * Copyright 2022-2027 中国信息通信研究院云计算与大数据研究所
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 
package com.service.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.common.calculation.TimeUtil;
import com.common.constant.AccountConstant;
import com.common.constant.ChkuplogConstant;
import com.common.constant.ParamConstant;
import com.common.constant.TrancfgConstant;
import com.common.constant.UniformityConstant;
import com.common.context.SpringContextUtils;
import com.common.util.CommUtil;
import com.localMapper.LocalTranLogMapper;
import com.localMapper.ParamcfgMapper;
import com.mapper.ReadDataConfig;
import com.mapper.ReadTranConfig;
import com.mapper.Salary;
import com.mapper.UniformityMapper;
import com.pojo.ChkuplogCount;
import com.pojo.DataConfig;
import com.pojo.Paramcfg;
import com.pojo.SalaryBranchCount;
import com.pojo.Trancfg;
import com.pojo.TranlogCount;
import com.service.DispatchService;

@Service
@Scope("prototype")
public class DispatchServiceImpl implements DispatchService,Runnable {

    private final Logger logger = LoggerFactory.getLogger(DispatchServiceImpl.class);
    
    private StringBuffer buf = new StringBuffer();
    @Autowired
    private ReadTranConfig readTranConfig;
    @Autowired
    private UniformityMapper uniformityMapper;
    @Autowired
    private LocalTranLogMapper localTranLogMapper;
    @Autowired
    private ReadDataConfig readDataCfg;
    @Autowired
    private Salary salary;
    @Autowired
    private ParamcfgMapper paramcfgMapper;
    private String datacfg_id = "";
    private String trancfg_testid = "";
    private String process_id;
    private String isolationLevel = "";
    
	@Override
	public void run() {
		long now = System.currentTimeMillis();
        DataConfig df = readDataCfg.readDataCfg(datacfg_id);
        if(df == null) {
        	return;
        }
		DataCleanServiceImpl dataCleanServiceImpl = SpringContextUtils.getBean(DataCleanServiceImpl.class);//进行业务数据清理
		dataCleanServiceImpl.run();
		Paramcfg paramcfg = paramcfgMapper.getParamByName(ParamConstant.PARAM_START_UNIFORMITY);
		BigDecimal afterAccountBale =BigDecimal.ZERO;
		System.out.println("开始执行一致性测试："+CommUtil.getNowTime());
        if(UniformityConstant.UNIFORMITY_START_UNIFORMITY.equals(paramcfg.getParam_value())) {
        	afterAccountBale = uniformityMapper.sumAccount();
        }
        uniformityCheck(afterAccountBale);//测试前一致性
		System.out.println("结束执行一致性测试："+CommUtil.getNowTime());
		printDataConfigure(df);//拼装数据配置输出
		AtomicityServiceImpl atomicityCommit = SpringContextUtils.getBean(AtomicityServiceImpl.class);
		AtomicityServiceImpl atomicityUnCommit = SpringContextUtils.getBean(AtomicityServiceImpl.class);
    	startAtomicityCheck(atomicityCommit,atomicityUnCommit,df);//开始原子性检测
    	IsolationMainServiceImpl isolationMain = SpringContextUtils.getBean(IsolationMainServiceImpl.class);
    	startIsolationCheck(isolationMain,df);//开始隔离性检测
		Map<String,Integer> threadConfigure = new HashMap<String,Integer>();
		Map<String,Trancfg> tfConfigure = new HashMap<String,Trancfg>();
	    List<SalaryBranchCount> branchCountList = salary.countBranchSalary();
		printRunConfigure(threadConfigure,branchCountList,tfConfigure);//拼装运行配置输出
		System.out.println("开始执行业务测试："+CommUtil.getNowTime());
        //开始初始化线程配置
        int threadNum = threadConfigure.get("transferProcNum")+threadConfigure.get("salaryProcNum")
        				+threadConfigure.get("queryProcNum")+threadConfigure.get("depositProcNum")+
        				threadConfigure.get("withdrawProcNum");
        ExecutorService executor = Executors.newFixedThreadPool(threadNum);
        //开始启动线程
        beginRunThread(executor,threadConfigure,df,branchCountList,tfConfigure);
        //关闭线程池
        executor.shutdown();
        try {
            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            logger.error(" DispatchServiceImpl run thread InterruptedException {} ", e);
        }
		System.out.println("结束执行业务测试："+CommUtil.getNowTime());
		stopAtomicityCheck(atomicityCommit,atomicityUnCommit);//停止原子性检测
		stopIsolationCheck(isolationMain);//停止隔离性检测
		System.out.println("开始执行一致性测试："+CommUtil.getNowTime());
        uniformityCheck(afterAccountBale);//测试后检测一致性
		System.out.println("结束执行一致性测试："+CommUtil.getNowTime());
        durabilityCheck();//持久性检测
        //拼装输出结果
        printThreadOut(buf,System.currentTimeMillis()-now,threadConfigure,branchCountList);
	}

	private void durabilityCheck() {
		DurabilityServiceImpl durabilityServiceImpl = SpringContextUtils.getBean(DurabilityServiceImpl.class);
		durabilityServiceImpl.run();
	}

	/**
	 * 停止隔离性检测
	 * @param isolationMain
	 */
	private void stopIsolationCheck(IsolationMainServiceImpl isolationMain) {
		isolationMain.setStop(true);
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			logger.error("DispatchServiceImpl run stopIsolationCheck e {} ",e);
		}		
	}

	/**
	 * 开始隔离性检测
	 * @param isolationMain
	 * @param df
	 */
	private void startIsolationCheck(IsolationMainServiceImpl isolationMain, DataConfig df) {
		isolationMain.setDatacfg_accnum(df.getDatacfg_accnum());
		isolationMain.setIsolationLevel(isolationLevel);
		isolationMain.start();		
	}


	/**
	 * 停止原子性检测
	 * @param atomicityCommit
	 * @param atomicityUnCommit
	 */
	private void stopAtomicityCheck(AtomicityServiceImpl atomicityCommit, AtomicityServiceImpl atomicityUnCommit) {
		atomicityCommit.setStop(true);
		atomicityUnCommit.setStop(true);
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			logger.error("DispatchServiceImpl run stopAtomicityCheck e {} ",e);
		}
	}

	/**
	 * 开启原子性检测
	 * @param atomicityCommit
	 * @param atomicityUnCommit
	 * @param df 
	 */
	private void startAtomicityCheck(AtomicityServiceImpl atomicityCommit, AtomicityServiceImpl atomicityUnCommit, DataConfig df) {
		atomicityCommit.setType("1");
		atomicityCommit.setPrex("80");
		atomicityCommit.setDatacfg_accnum(df.getDatacfg_accnum());
		atomicityCommit.start();
		atomicityUnCommit.setType("2");
		atomicityCommit.setPrex("81");
		atomicityUnCommit.setDatacfg_accnum(df.getDatacfg_accnum());
		atomicityUnCommit.start();
	}


	private void uniformityCheck(BigDecimal afterAccountBale) {
		if(afterAccountBale==null) {
			afterAccountBale = BigDecimal.ZERO;
		}
		//开启一致性线程
		UniformityServiceImpl uniformityService = SpringContextUtils.getBean(UniformityServiceImpl.class);
		uniformityService.setAfterAccountBale(afterAccountBale);
		uniformityService.setProcess_id(process_id);
		uniformityService.run();
        logger.info(" DispatchServiceImpl run thread UniformityServiceImpl start ");		
	}


	private void beginRunThread( ExecutorService executor, Map<String, Integer> threadConfigure, DataConfig df, List<SalaryBranchCount> branchCountList, Map<String, Trancfg> tfConfigure) {
		//转账线程启动
		for (int i = 0; i < threadConfigure.get("transferProcNum"); i++) {
			if(threadConfigure.get("transferRunNum")>0) {
				TransferServiceImpl transferService = SpringContextUtils.getBean(TransferServiceImpl.class);
	        	transferService.setDatacfg_accnum(df.getDatacfg_accnum());
	        	transferService.setNum(threadConfigure.get("transferRunNum")/threadConfigure.get("transferProcNum"));
	        	transferService.setProcess_id(process_id);
	        	transferService.setTrancfgType(TrancfgConstant.TRANCFG_ACCOUNTS_TRANSFER);
	        	transferService.setTf(tfConfigure.get("transferTf"));
	        	executor.submit(transferService);
			}
		}
		//代发工资线程启动
        for (int i = 0; i < threadConfigure.get("salaryProcNum"); i++) {
        	if(threadConfigure.get("salaryRunNum")>0) {
        		SalaryServiceImpl salaryServiceImpl = SpringContextUtils.getBean(SalaryServiceImpl.class);
              	int count = (int) Math.floor(threadConfigure.get("salaryRunNum")/(double)threadConfigure.get("salaryProcNum"));
              	int mod = threadConfigure.get("salaryRunNum")%threadConfigure.get("salaryProcNum");
              	salaryServiceImpl.setSalaryRepeatNum(threadConfigure.get("salaryRepeatNum"));
              	salaryServiceImpl.setProcess_id(process_id);
              	if(i<mod) {
                	salaryServiceImpl.setBranchCountList(branchCountList.subList(i*(count+1), (count+1)+i*(count+1)));
              	}else {
              		int start = mod*(count+1)+(i-mod)*count;
                	salaryServiceImpl.setBranchCountList(branchCountList.subList(start, start + count));
              	}
              	salaryServiceImpl.setTf(tfConfigure.get("salaryTf"));
            	executor.submit(salaryServiceImpl);
        	}
		}
        //账户查询线程启动
        for (int i = 0; i < threadConfigure.get("queryProcNum"); i++) {
        	if(threadConfigure.get("queryRunNum")>0) {
        		QueryAccountServiceImpl queryAccountServiceImpl = SpringContextUtils.getBean(QueryAccountServiceImpl.class);
            	queryAccountServiceImpl.setDatacfg_accnum(df.getDatacfg_accnum());
            	queryAccountServiceImpl.setProcess_id(process_id);
            	queryAccountServiceImpl.setNum(threadConfigure.get("queryRunNum")/threadConfigure.get("queryProcNum"));
            	queryAccountServiceImpl.setTf(tfConfigure.get("queryTf"));
            	executor.submit(queryAccountServiceImpl);
        	}
		}		
		//存款线程启动
		for (int i = 0; i < threadConfigure.get("depositProcNum"); i++) {
			if(threadConfigure.get("depositRunNum")>0) {
				WithdrawMoneyServiceImpl depositMoneyService = SpringContextUtils.getBean(WithdrawMoneyServiceImpl.class);
				depositMoneyService.setDatacfg_accnum(df.getDatacfg_accnum());
				depositMoneyService.setNum(threadConfigure.get("depositRunNum")/threadConfigure.get("depositProcNum"));
	        	depositMoneyService.setTrancfgType(TrancfgConstant.TRANCFG_ACCOUNTS_DEPOSIT);
	        	depositMoneyService.setProcess_id(process_id);
	        	depositMoneyService.setTf(tfConfigure.get("transferTf"));
	        	executor.submit(depositMoneyService);
			}
		}
		//取款线程启动
		for (int i = 0; i < threadConfigure.get("withdrawProcNum"); i++) {
			if(threadConfigure.get("withdrawRunNum")>0) {
				DepositMoneyServiceImpl withdrawMoneyService = SpringContextUtils.getBean(DepositMoneyServiceImpl.class);
				withdrawMoneyService.setDatacfg_accnum(df.getDatacfg_accnum());
				withdrawMoneyService.setNum(threadConfigure.get("withdrawRunNum")/threadConfigure.get("withdrawProcNum"));
				withdrawMoneyService.setTrancfgType(TrancfgConstant.TRANCFG_ACCOUNTS_WITHDRAW);
				withdrawMoneyService.setTf(tfConfigure.get("transferTf"));
				withdrawMoneyService.setProcess_id(process_id);
	        	executor.submit(withdrawMoneyService);
			}
		}
	}


	private void printRunConfigure(Map<String, Integer> threadConfigure, List<SalaryBranchCount> branchCountList, Map<String, Trancfg> tfConfigure) {
		 	Trancfg param = new Trancfg();
	        param.setTrancfg_testid(trancfg_testid);
	      	List<Trancfg> tfList = readTranConfig.readTranConfig(param);
	      	threadConfigure.put("transferRunNum", 0);
	      	threadConfigure.put("transferProcNum", 0);
	      	threadConfigure.put("salaryRunNum", 0);
	      	threadConfigure.put("salaryProcNum", 0);
	      	threadConfigure.put("queryRunNum", 0);
	      	threadConfigure.put("queryProcNum", 0);
	      	threadConfigure.put("salaryRepeatNum", 0);
			//代发工资线程数初始化
	      	if(tfList!=null&&tfList.size()>0) {
	    		buf.append("运行配置：");
	      		for(Trancfg tf:tfList) {
	      			buf.append("\n");
	      			buf.append("\t");
	      			if(tf.getTrancfg_id().equals(TrancfgConstant.TRANCFG_ACCOUNTS_TRANSFER)) {
	      				buf.append("转账交易：").append(tf.getTrancfg_runnum()).append("笔").append("，");
	      				buf.append("转账线程：").append(tf.getTrancfg_procnum()).append("；");
	      		      	threadConfigure.put("transferRunNum", tf.getTrancfg_runnum());
	      		      	threadConfigure.put("transferProcNum", tf.getTrancfg_procnum());
	      		      	tfConfigure.put("transferTf",tf);
	      			}else if(tf.getTrancfg_id().equals(TrancfgConstant.TRANCFG_ACCOUNTS_SALARY)) {
	      				if(branchCountList.size()!=0) {
	      			      	threadConfigure.put("salaryRunNum", branchCountList.size());
		      			    threadConfigure.put("salaryProcNum",tf.getTrancfg_procnum());
	      				}
	      			    threadConfigure.put("salaryRepeatNum",tf.getTrancfg_runnum());
	      				int salaryTotal = 0;
	      				for(SalaryBranchCount salaryBranchCount : branchCountList) {
	      					salaryTotal+=salaryBranchCount.getNum();
	      				}
	      				buf.append("代发工资：").append(salaryTotal).append("条(").append(branchCountList.size())
	      				.append("个代发网点，重复代发").append(tf.getTrancfg_runnum()).append("次，共").append((salaryTotal*tf.getTrancfg_runnum())/2).append("笔)").append("，");
	      				buf.append("代发线程：").append(threadConfigure.get("salaryProcNum")).append("；");
	      			    threadConfigure.put("salaryTotalNum",salaryTotal*tf.getTrancfg_runnum());
	      		      	tfConfigure.put("salaryTf",tf);
	      			}else if(tf.getTrancfg_id().equals(TrancfgConstant.TRANCFG_ACCOUNTS_QUERY)) {
	      				buf.append("账户查询：").append(tf.getTrancfg_runnum()).append("笔").append("，");
	      				buf.append("查询线程：").append(tf.getTrancfg_procnum()).append("；");
	      				threadConfigure.put("queryRunNum", tf.getTrancfg_runnum());
	      		      	threadConfigure.put("queryProcNum", tf.getTrancfg_procnum());
	      		      	tfConfigure.put("queryTf",tf);
	      			}else if(tf.getTrancfg_id().equals(TrancfgConstant.TRANCFG_ACCOUNTS_DEPOSIT)) {
	      				buf.append("账户存款：").append(tf.getTrancfg_runnum()).append("笔").append("，");
	      				buf.append("存款线程：").append(tf.getTrancfg_procnum()).append("；");
	       				threadConfigure.put("depositRunNum", tf.getTrancfg_runnum());
	      		      	threadConfigure.put("depositProcNum", tf.getTrancfg_procnum());
	      		      	tfConfigure.put("depositTf",tf);
	      			}else if(tf.getTrancfg_id().equals(TrancfgConstant.TRANCFG_ACCOUNTS_WITHDRAW)) {
	      				buf.append("账户取款：").append(tf.getTrancfg_runnum()).append("笔").append("，");
	      				buf.append("取款线程：").append(tf.getTrancfg_procnum()).append("；");
	       				threadConfigure.put("withdrawRunNum", tf.getTrancfg_runnum());
	      		      	threadConfigure.put("withdrawProcNum", tf.getTrancfg_procnum());
	      		      	tfConfigure.put("withdrawTf",tf);
	      			}else if(tf.getTrancfg_id().equals(TrancfgConstant.TRANCFG_ACCOUNTS_INVENTORY)) {
	      				buf.append("资产盘点：").append(tf.getTrancfg_runnum()).append("笔").append("，");
	      				buf.append("盘点线程：").append(tf.getTrancfg_procnum()).append("；");
	      				threadConfigure.put("inventoryRunNum", tf.getTrancfg_runnum());
	      		      	threadConfigure.put("inventoryProcNum", tf.getTrancfg_procnum());
	      			}
	      		}
	      	}		
	}


	/**
	 * 拼装数据格式输出
	 * @param df
	 */
	private void printDataConfigure(DataConfig df) {
		buf.append("\n");
		buf.append("数据配置：");
		buf.append("\n");
		buf.append("\t");
		buf.append("网点数").append(df.getDatacfg_brhnum()).append("，");
		buf.append("科目数").append(df.getDatacfg_sjnonum()).append("，");
		buf.append("客户数").append(df.getDatacfg_cusnum()).append("，");
		buf.append("账户数").append(df.getDatacfg_accnum()).append("，");
		buf.append("\n");		
	}


	/**
	 * 拼装输出返回
	 * @param buf
	 * @param costTotal
	 * @param threadConfigure
	 * @param branchCountList 
	 */
	private void printThreadOut(StringBuffer buf, long costTotal, Map<String, Integer> threadConfigure, List<SalaryBranchCount> branchCountList) {
		List<TranlogCount> costList = localTranLogMapper.tranlogCostTimeCount(process_id);
		Map<String,TranlogCount> costMap = new HashMap<String,TranlogCount>();
		for(TranlogCount tranlogCount:costList) {
			costMap.put(tranlogCount.getTrancfg_type(), tranlogCount);
		}
		buf.append("\n");
		buf.append("业务测试明细：");
		buf.append("\n");
		buf.append("\t");
		buf.append("测试总耗时：").append(TimeUtil.formatDuration(costTotal));
		buf.append("\n");
		if(costMap.containsKey(TrancfgConstant.TRANCFG_ACCOUNTS_TRANSFER)) {
			buf.append("\t");
			TranlogCount tc = costMap.get(TrancfgConstant.TRANCFG_ACCOUNTS_TRANSFER);
			buf.append(threadConfigure.get("transferProcNum")).append("线程并发转账交易").append(tc.getNum()).append("笔，");
			buf.append("总耗时").append(TimeUtil.formatDuration(tc.getTotal_cost().longValue()/threadConfigure.get("transferProcNum"))).append("，");
			buf.append("平均耗时").append(TimeUtil.formatDuration(tc.getAvg_cost().longValue())).append("，");
			buf.append("最大耗时").append(TimeUtil.formatDuration(tc.getMax_cost().longValue())).append("，");
			long cost = tc.getTotal_cost().longValue()/threadConfigure.get("transferProcNum")/1000;
			if(cost==0) {
				buf.append("TPS每秒 ").append((tc.getNum()));
			}else {
				buf.append("TPS每秒 ").append((tc.getNum())/cost);
			}
		}else {
			buf.append("\t");
			buf.append(threadConfigure.get("transferProcNum")).append("线程并发转账交易").append(0).append("笔，");
			buf.append("总耗时").append(0).append("，");
			buf.append("平均耗时").append(0).append("，");
			buf.append("最大耗时").append(0).append("，");
			buf.append("TPS每秒 ").append(0);

		}
		buf.append("\n");
		if(costMap.containsKey(TrancfgConstant.TRANCFG_ACCOUNTS_QUERY)) {
			buf.append("\t");
			TranlogCount tc = costMap.get(TrancfgConstant.TRANCFG_ACCOUNTS_QUERY);
			buf.append(threadConfigure.get("queryProcNum")).append("线程并发账户查询").append(tc.getNum()).append("笔，");
			buf.append("总耗时").append(TimeUtil.formatDuration(tc.getTotal_cost().longValue()/threadConfigure.get("queryProcNum"))).append("，");
			buf.append("平均耗时").append(TimeUtil.formatDuration(tc.getAvg_cost().longValue())).append("，");
			buf.append("最大耗时").append(TimeUtil.formatDuration(tc.getMax_cost().longValue())).append("，");
			long cost = tc.getTotal_cost().longValue()/threadConfigure.get("queryProcNum")/1000;
			if(cost==0) {
				buf.append("TPS每秒 ").append((tc.getNum()));
			}else {
				buf.append("TPS每秒 ").append((tc.getNum())/cost);
			}

		}else {
			buf.append("\t");
			buf.append(threadConfigure.get("queryProcNum")).append("线程并发账户查询").append(0).append("笔，");
			buf.append("总耗时").append(0).append("，");
			buf.append("平均耗时").append(0).append("，");
			buf.append("最大耗时").append(0).append("，");
			buf.append("TPS每秒 ").append(0);
		}
		buf.append("\n");
		if(costMap.containsKey(TrancfgConstant.TRANCFG_ACCOUNTS_DEPOSIT)) {
			buf.append("\t");
			TranlogCount tc = costMap.get(TrancfgConstant.TRANCFG_ACCOUNTS_DEPOSIT);
			buf.append(threadConfigure.get("depositProcNum")).append("线程并发账户存款").append(tc.getNum()).append("笔，");
			buf.append("总耗时").append(TimeUtil.formatDuration(tc.getTotal_cost().longValue()/threadConfigure.get("depositProcNum"))).append("，");
			buf.append("平均耗时").append(TimeUtil.formatDuration(tc.getAvg_cost().longValue())).append("，");
			buf.append("最大耗时").append(TimeUtil.formatDuration(tc.getMax_cost().longValue())).append("，");
			long cost = tc.getTotal_cost().longValue()/threadConfigure.get("depositProcNum")/1000;
			if(cost==0) {
				buf.append("TPS每秒 ").append((tc.getNum()));
			}else {
				buf.append("TPS每秒 ").append((tc.getNum())/cost);
			}
		}else {
			buf.append("\t");
			buf.append(threadConfigure.get("depositProcNum")).append("线程并发账户存款").append(0).append("笔，");
			buf.append("总耗时").append(0).append("，");
			buf.append("平均耗时").append(0).append("，");
			buf.append("最大耗时").append(0).append("，");
			buf.append("TPS每秒 ").append(0);
		}
		buf.append("\n");
		if(costMap.containsKey(TrancfgConstant.TRANCFG_ACCOUNTS_WITHDRAW)) {
			buf.append("\t");
			TranlogCount tc = costMap.get(TrancfgConstant.TRANCFG_ACCOUNTS_WITHDRAW);
			buf.append(threadConfigure.get("withdrawProcNum")).append("线程并发账户取款").append(tc.getNum()).append("笔，");
			buf.append("总耗时").append(TimeUtil.formatDuration(tc.getTotal_cost().longValue()/threadConfigure.get("withdrawProcNum"))).append("，");
			buf.append("平均耗时").append(TimeUtil.formatDuration(tc.getAvg_cost().longValue())).append("，");
			buf.append("最大耗时").append(TimeUtil.formatDuration(tc.getMax_cost().longValue())).append("，");
			long cost = tc.getTotal_cost().longValue()/threadConfigure.get("withdrawProcNum")/1000;
			if(cost==0) {
				buf.append("TPS每秒 ").append((tc.getNum()));
			}else {
				buf.append("TPS每秒 ").append((tc.getNum())/cost);
			}
		}else {
			buf.append("\t");
			buf.append(threadConfigure.get("withdrawProcNum")).append("线程并发账户取款").append(0).append("笔，");
			buf.append("总耗时").append(0).append("，");
			buf.append("平均耗时").append(0).append("，");
			buf.append("最大耗时").append(0).append("，");
			buf.append("TPS每秒 ").append(0);
		}
		buf.append("\n");
		if(costMap.containsKey(TrancfgConstant.TRANCFG_ACCOUNTS_SALARY)) {
			buf.append("\t");
			TranlogCount tc = costMap.get(TrancfgConstant.TRANCFG_ACCOUNTS_SALARY);
			buf.append(threadConfigure.get("salaryProcNum")).append("线程并发代发工资").append(threadConfigure.get("salaryTotalNum")/2).append("笔").append("(").append(branchCountList.size())
				.append("个代发网点，重复代发").append(threadConfigure.get("salaryRepeatNum")).append("次，共").append(threadConfigure.get("salaryTotalNum")/2).append("笔)").append("，");
			buf.append("总耗时").append(TimeUtil.formatDuration(tc.getTotal_cost().longValue()/threadConfigure.get("salaryProcNum"))).append("，");
			buf.append("平均耗时").append(TimeUtil.formatDuration(tc.getAvg_cost().longValue())).append("，");
			buf.append("最大耗时").append(TimeUtil.formatDuration(tc.getMax_cost().longValue()));
		}else {
			buf.append("\t");
			buf.append(threadConfigure.get("salaryProcNum")).append("线程并发代发工资").append(0).append("笔，");
			buf.append("总耗时").append(0).append("，");
			buf.append("平均耗时").append(0).append("，");
			buf.append("最大耗时").append(0);
		}
		buf.append("\n");
		buf.append("\t");
		System.out.println("开始执行资产盘点："+CommUtil.getNowTime());
		if(threadConfigure.get("inventoryRunNum")!=null&&threadConfigure.get("inventoryRunNum")>0) {
			long cost = System.currentTimeMillis();
			List<String> customerList = uniformityMapper.accountInventory();
			if(customerList!=null&&customerList.size()>0) {
				logger.info(" DispatchServiceImpl printThreadOut accountInventory failure customerList {} ",customerList);
				buf.append("资产盘点失败，总耗时").append(TimeUtil.formatDuration(System.currentTimeMillis()-cost));
			}else {
				logger.info(" DispatchServiceImpl printThreadOut accountInventory success ");
				buf.append("资产盘点成功，总耗时").append(TimeUtil.formatDuration(System.currentTimeMillis()-cost));
			}
		}else {
			buf.append("资产盘点0笔");
		}
		System.out.println("结束执行资产盘点："+CommUtil.getNowTime());
		buf.append("\n");
		buf.append("ACID测试明细：");
		buf.append("\n");
		List<ChkuplogCount> chkuplogCountList = uniformityMapper.chkuplogCount();
		Map<String,ChkuplogCount> chkuplogCountMap = new HashMap<String,ChkuplogCount>();
		for(ChkuplogCount chkuplogCount : chkuplogCountList) {
			chkuplogCountMap.put(chkuplogCount.getChkuplog_type().trim()+chkuplogCount.getChkuplog_success().trim(), chkuplogCount);
		}
		int uniformitySuccess = 0;
		int uniformityFailure = 0;
		int atomicitySuccess = 0;
		int atomicityFailure = 0;
		int isolationSuccess = 0;
		int isolationFailure = 0; 
		int durabilitySuccess = 0;
		int durabilityFailure = 0; 
		if(chkuplogCountMap.containsKey(ChkuplogConstant.CHKUPLOG_TYPE_C+AccountConstant.ACCOUNT_TRAN_SUCCESS)) {
			ChkuplogCount cc = chkuplogCountMap.get(ChkuplogConstant.CHKUPLOG_TYPE_C+AccountConstant.ACCOUNT_TRAN_SUCCESS);
			uniformitySuccess = cc.getNum();
		}
		if(chkuplogCountMap.containsKey(ChkuplogConstant.CHKUPLOG_TYPE_C+AccountConstant.ACCOUNT_TRAN_FAILURE)) {
			ChkuplogCount cc = chkuplogCountMap.get(ChkuplogConstant.CHKUPLOG_TYPE_C+AccountConstant.ACCOUNT_TRAN_FAILURE);
			uniformityFailure = cc.getNum();
		}
		if(chkuplogCountMap.containsKey(ChkuplogConstant.CHKUPLOG_TYPE_A+AccountConstant.ACCOUNT_TRAN_SUCCESS)) {
			ChkuplogCount cc = chkuplogCountMap.get(ChkuplogConstant.CHKUPLOG_TYPE_A+AccountConstant.ACCOUNT_TRAN_SUCCESS);
			atomicitySuccess = cc.getNum();
		}
		if(chkuplogCountMap.containsKey(ChkuplogConstant.CHKUPLOG_TYPE_A+AccountConstant.ACCOUNT_TRAN_FAILURE)) {
			ChkuplogCount cc = chkuplogCountMap.get(ChkuplogConstant.CHKUPLOG_TYPE_A+AccountConstant.ACCOUNT_TRAN_FAILURE);
			atomicityFailure = cc.getNum();
		}
		if(chkuplogCountMap.containsKey(ChkuplogConstant.CHKUPLOG_TYPE_I+AccountConstant.ACCOUNT_TRAN_SUCCESS)) {
			ChkuplogCount cc = chkuplogCountMap.get(ChkuplogConstant.CHKUPLOG_TYPE_I+AccountConstant.ACCOUNT_TRAN_SUCCESS);
			isolationSuccess = cc.getNum();
		}
		if(chkuplogCountMap.containsKey(ChkuplogConstant.CHKUPLOG_TYPE_I+AccountConstant.ACCOUNT_TRAN_FAILURE)) {
			ChkuplogCount cc = chkuplogCountMap.get(ChkuplogConstant.CHKUPLOG_TYPE_I+AccountConstant.ACCOUNT_TRAN_FAILURE);
			isolationFailure = cc.getNum();
		}
		if(chkuplogCountMap.containsKey(ChkuplogConstant.CHKUPLOG_TYPE_D+AccountConstant.ACCOUNT_TRAN_SUCCESS)) {
			ChkuplogCount cc = chkuplogCountMap.get(ChkuplogConstant.CHKUPLOG_TYPE_D+AccountConstant.ACCOUNT_TRAN_SUCCESS);
			durabilitySuccess = cc.getNum();
		}
		if(chkuplogCountMap.containsKey(ChkuplogConstant.CHKUPLOG_TYPE_D+AccountConstant.ACCOUNT_TRAN_FAILURE)) {
			ChkuplogCount cc = chkuplogCountMap.get(ChkuplogConstant.CHKUPLOG_TYPE_D+AccountConstant.ACCOUNT_TRAN_FAILURE);
			durabilityFailure = cc.getNum();
		}
		buf.append("\t");
		buf.append("一致性测试").append(uniformitySuccess+uniformityFailure).append("笔，");
		buf.append("成功").append(uniformitySuccess).append("笔，");
		buf.append("失败").append(uniformityFailure).append("笔；");
		buf.append("\n");
		buf.append("\t");
		buf.append("原子性测试").append(atomicitySuccess+atomicityFailure).append("笔，");
		buf.append("成功").append(atomicitySuccess).append("笔，");
		buf.append("失败").append(atomicityFailure).append("笔；");
		buf.append("\n");
		buf.append("\t");
		buf.append("隔离性测试").append(isolationSuccess+isolationFailure).append("笔，");
		buf.append("成功").append(isolationSuccess).append("笔，");
		buf.append("失败").append(isolationFailure).append("笔；");
		buf.append("\n");
		buf.append("\t");
		buf.append("持久性测试").append(durabilitySuccess+durabilityFailure).append("笔，");
		buf.append("成功").append(durabilitySuccess).append("笔，");
		buf.append("失败").append(durabilityFailure).append("笔；");
		buf.append("\n");
		System.out.println(buf.toString());
	}
	public String getDatacfg_id() {
		return datacfg_id;
	}


	public void setDatacfg_id(String datacfg_id) {
		this.datacfg_id = datacfg_id;
	}


	public String getTrancfg_testid() {
		return trancfg_testid;
	}

	public void setTrancfg_testid(String trancfg_testid) {
		this.trancfg_testid = trancfg_testid;
	}

	public String getIsolationLevel() {
		return isolationLevel;
	}

	public void setIsolationLevel(String isolationLevel) {
		this.isolationLevel = isolationLevel;
	}

	@Override
	public String testTask(String datacfg_id, String trancfg_testid, String isolationLevel) {
		DispatchServiceImpl dispatchServiceImpl = SpringContextUtils.getBean(DispatchServiceImpl.class);
		dispatchServiceImpl.setDatacfg_id(datacfg_id);
		dispatchServiceImpl.setTrancfg_testid(trancfg_testid);
		dispatchServiceImpl.setIsolationLevel(isolationLevel);
		dispatchServiceImpl.run();
		return null;
	}

	public String getProcess_id() {
		return process_id;
	}

	public void setProcess_id(String process_id) {
		this.process_id = process_id;
	}


}